import React, { useContext, useEffect, useState } from "react";
import { Input, Form, Table, Popconfirm, Button, Select } from "antd";
import { DeleteOutlined, PlusOutlined } from "@ant-design/icons";
import InputNumberComponent from "@/components/iteration/InputNumberComponent";
import CheckboxComponent from "@/components/iteration/CheckboxComponent";
import PropTypes from "prop-types";

const EditableContext = React.createContext(null);
const EditableRow = ({ ...props }) => {
  const [form] = Form.useForm();

  if (props.pushFormList) {
    props.pushFormList(form);
    delete props.pushFormList;
  }

  const onBlur = (e) => {
    // 判断是否是行失去焦点
    if (e.relatedTarget && e.currentTarget.contains(e.relatedTarget)) {
      return;
    }
    props.onBlur && props.onBlur(form);
  };

  return (
    <Form form={form} component={false}>
      <EditableContext.Provider value={form}>
        <tr {...props} onBlur={onBlur} />
      </EditableContext.Provider>
    </Form>
  );
};
EditableRow.propTypes = {
  pushFormList: PropTypes.func,
  onBlur: PropTypes.func,
};

/**
 *
 * @param {Object} record 行数据
 * @param {Number} index 行下标
 * @param {String} dataIndex 列字段
 * @param {String} component 单元格组件类型名称，Input[default]/InputNumber/Select/Checkbox
 * @param {Array} componentData 单元格Select组件选项数据
 * @param {Array} rules 单元格组件校验规则，对Checkbox组件无效
 * @param {String} resType Checkbox 结果返回类型，number/boolean[default]
 * @param {Function} disabled 禁用选项条件
 * @param {Function} handleSave 保存回调函数 function handleSave(record, index)
 * @returns
 */
const EditableCell = ({
  record,
  dataIndex,
  component,
  componentData = [],
  rules,
  resType,
  disabled,
  dataSource,
  children,
  onMouseEnter = () => {},
  ...restProps
}) => {
  const form = useContext(EditableContext);

  useEffect(() => {
    const [, value] = children;
    if (value && typeof value !== "object" && !form.getFieldValue(dataIndex)) {
      form.setFieldValue(dataIndex, value);
    }
  }, [children, dataIndex, form]);

  const components = {
    Input: (
      <Input
        variant="borderless"
        disabled={disabled ? disabled(record[dataIndex], record) : false}
        autoComplete="off"
      />
    ),
    InputNumber: (
      <InputNumberComponent
        min={1}
        variant="borderless"
        disabled={disabled ? disabled(record[dataIndex], record) : false}
        autoComplete="off"
      />
    ),
    Select: (
      <Select
        showSearch
        variant="borderless"
        options={componentData}
        allowClear
        disabled={disabled ? disabled(record[dataIndex], record) : false}
      />
    ),
    Checkbox: (
      <CheckboxComponent
        restype={resType}
        disabled={disabled ? disabled(record[dataIndex], record) : false}
        temp={children}
      />
    ),
  };

  const element = (
    <Form.Item name={dataIndex} rules={rules || []} autoComplete="off">
      {components[component] || <div className="text">{children}</div>}
    </Form.Item>
  );

  return <td {...restProps}>{component ? element : <div className="text">{children}</div>}</td>;
};
EditableCell.propTypes = {
  record: PropTypes.object,
  dataIndex: PropTypes.string,
  component: PropTypes.string,
  componentData: PropTypes.array,
  rules: PropTypes.array,
  resType: PropTypes.string,
  disabled: PropTypes.func,
  dataSource: PropTypes.array,
  onMouseEnter: PropTypes.func,
  children: PropTypes.node,
};

const EditorTableComponent = ({
  dataSource: datas,
  defaultColumns,
  onChange,
  formList,
  isOptions = true,
  ...resProp
}) => {
  const [dataSource, setDataSource] = useState([]);

  useEffect(() => {
    !!datas.length && setDataSource(datas);
  }, [datas]);

  // 添加行
  const onInset = () => {
    const data = dataSource.concat({ key: dataSource.length + 1 });
    setDataSource(data);
  };

  // 删除行
  const handleDelete = (key) => {
    const newData = dataSource.filter((item) => item.key !== key);
    setDataSource(newData);
    onChange && onChange(newData);
  };

  // 保存数据
  const handleSave = (row, index) => {
    const newData = [...dataSource];
    newData[index] = row;
    setDataSource(newData);
    onChange && onChange(newData);
  };

  // 操作列
  const optionsColums = {
    title: (
      <Button type="link" icon={<PlusOutlined />} onClick={onInset}>
        添加行
      </Button>
    ),
    width: "120px",
    fixed: "right",
    render: (_, record) => (
      <Popconfirm title="Sure to delete?" onConfirm={() => handleDelete(record.key)}>
        <Button type="link" danger icon={<DeleteOutlined />}>
          删除行
        </Button>
      </Popconfirm>
    ),
  };

  const columns = defaultColumns.map((col) => {
    const onCell = (record) => {
      return { record, ...col, rules: col.component === "Checkbox" ? undefined : col.rules, dataSource };
    };
    return col.component ? { ...col, onCell: onCell } : col;
  });

  return (
    <Table
      {...resProp}
      components={{ body: { row: EditableRow, cell: EditableCell } }}
      dataSource={dataSource}
      columns={columns.concat(isOptions === true ? optionsColums : [])}
      pagination={{ hideOnSinglePage: true, defaultPageSize: "50" }}
      onRow={(record, index) => {
        return {
          onBlur: (form) => {
            form.validateFields().then((values) => {
              handleSave({ ...record, ...values }, index);
            });
          },
          pushFormList: (form) => formList.add(form),
        };
      }}
    />
  );
};
EditorTableComponent.propTypes = {
  dataSource: PropTypes.array,
  defaultColumns: PropTypes.array,
  onChange: PropTypes.func,
  formList: PropTypes.object,
  isOptions: PropTypes.bool,
};

export default EditorTableComponent;
